﻿using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Sok.Munkae.ApplicationServices;
using Sok.Munkae.ApplicationServices.Membership;
using Sok.Munkae.Core;
using Sok.Munkae.Core.DataInterfaces;
using Sok.Munkae.Data;
using Sok.Munkae.Data.Tenant;
using Sok.Munkae.Tenant;
using Sok.Munkae.Web.FormsAuthentication;
using Sok.Munkae.Web.PresentationServices;

namespace Sok.Munkae.Web.CastleWindsor
{
    public class ComponentRegistrar
    {
        public static void AddComponentsTo(IWindsorContainer container)
        {
            AddTenantIdentifiersTo(container);
            AddRepositoriesTo(container);
            AddApplicationServicesTo(container);
            AddAuthenticationServicesTo(container);
            AddPresentationServicesTo(container);
            AddGenericDaoTo(container);
        }

        private static void AddAuthenticationServicesTo(IWindsorContainer container)
        {
            container.AddComponent<IAuthenticationProvider, FormsAuthenticationProvider>();
            container.AddComponent<IAuthenticationService, AuthenticationService>();
            container.AddComponent<IUserContext, ThreadUserContext>();
        }

        private static void AddPresentationServicesTo(IWindsorContainer container)
        {
            container.AddComponent<ProjectPresentationService>("ProjectPresentationService");
        }

        private static void AddTenantIdentifiersTo(IWindsorContainer container)
        {
            container.Register(
                Component.For<IHostNameProvider>().Named("HttpContextHostNameProvider")
                .ImplementedBy<HttpContextHostNameProvider>().LifeStyle.Transient);

            container.Register(
                Component.For<ITenantIdentifier>().Named("OrganizationContext")
                .ImplementedBy<OrganizationContext>().LifeStyle.Transient);

            container.Register(
                Component.For<ITenantIdentifier>().Named("HostNameIdentifier")
                    .ImplementedBy<HostNameIdentifier>().LifeStyle.Transient);

        }

        private static void AddRepositoriesTo(IWindsorContainer container)
        {
            container.Register(
                Component.For<IUserRepository>().Named("UserRepository")
                .ImplementedBy<UserRepository>().LifeStyle.Transient);
            
            container.Register(
                Component.For<IUserRepository>().Named("UserAuthenticationRepository")
                .ImplementedBy<UserRepository>()
                .ServiceOverrides(ServiceOverride.ForKey("tenantIdentifier").Eq("HostNameIdentifier"))
                .ServiceOverrides(ServiceOverride.ForKey("organizationRepository").Eq("TenantRepository"))
                .LifeStyle.Transient);

            //container.Register(
            //    Component.For<IUserAuthenticationRepository>().Named("UserAuthenticationRepository")
            //        .ImplementedBy<UserAuthenticationRepository>()
            //        .ServiceOverrides(ServiceOverride.ForKey("tenantIdentifier").Eq("HostNameIdentifier"))
            //        .LifeStyle.Transient);
            
            //container.Register(
            //    Component.For<IUserRepository>().Named("UserAuthenticationRepository")
            //        .ImplementedBy<UserAuthenticationRepository>()
            //        .ServiceOverrides(ServiceOverride.ForKey("tenantIdentifier").Eq("HostNameIdentifier"))
            //        .LifeStyle.Transient);

            container.Register(
                Component.For<IProjectRepository>().Named("ProjectRepository")
                .ImplementedBy<ProjectRepository>().LifeStyle.Transient);

            container.Register(
                Component.For<IOrganizationRepository>().Named("OrganizationRepository")
                .ImplementedBy<OrganizationRepository>().LifeStyle.Transient);
            
            container.Register(
                Component.For<IOrganizationRepository>().Named("TenantRepository")
                .ServiceOverrides(ServiceOverride.ForKey("tenantIdentifier").Eq("HostNameIdentifier"))
                .ImplementedBy<OrganizationRepository>().LifeStyle.Transient);

            //container.Register(Component.For<IRepository<Organization>>().Named("TenantRepository")
            //     .ImplementedBy<TenantRepository>().LifeStyle.Transient);
        }

        private static void AddApplicationServicesTo(IWindsorContainer container)
        {
            container.Register(
                Component.For<IMembershipService>().Named("MembershipService")
                .ImplementedBy<MembershipService>()
                .ServiceOverrides(ServiceOverride.ForKey("userRepository").Eq("UserAuthenticationRepository"))
                .LifeStyle.Transient);

            container.Register(
                Component.For<IProjectService>().Named("ProjectService")
                .ImplementedBy<ProjectService>().LifeStyle.Transient);
        }

        private static void AddGenericDaoTo(IWindsorContainer container)
        {
            container.AddComponent("repositoryHelperType", typeof (IDao<>), typeof (Dao<>));
        }
    }
}